#include "single_list_gp.h"

#include <string.h>

linked_list * list_create()
{
    linked_list *list = NULL;

    list = malloc(sizeof(linked_list));
    if (NULL == list) return NULL;

    list->dup = NULL;
    list->free = NULL;
    list->match = NULL;

    list->head = NULL;  //说明这个是不带头链表
    list->length = 0;

    return list;
}

void list_empty(linked_list *list)
{
    if (list == NULL ) return;
    list_node *ptr;

    while (list->head != NULL) {
        ptr = list->head;
        list->head = ptr->next;

        if (NULL != list->free) list->free(ptr->value);
        else free(ptr->value);

        ptr->next = NULL;
        free(ptr);
        ptr = NULL;
    }

}


void list_release(linked_list *list)
{
    if (list == NULL) return;

    list_empty(list);
    free(list);
    list = NULL;
}

linked_list *list_add_node_head(linked_list *list, void *value)
{
    if (list == NULL || value == NULL) return list;

    list_node *ptr = malloc(sizeof(list_node));
    if (NULL == ptr) return list;

    ptr->value = (int *) value;
    ptr->next = list->head;
    list->head = ptr;

    ++list->length;
    return list;
}

linked_list *list_add_node_tail(linked_list *list, void *value)
{
    if (list == NULL || value == NULL) return list;

    list_node *ptr = malloc(sizeof(list_node));
    if (NULL == ptr) return list;   
    ptr->value = value;
    ptr->next = NULL;

    list_node *tmp = list->head;
    if( NULL == tmp && list->length == 0){
        tmp = ptr;
        list->length ++;
        return list;
    } else {
        while (tmp -> next != NULL ) {
        tmp = tmp->next;
        }
    }

    tmp->next = ptr;
    list->length ++;
    return list;
}

void list_del_node(linked_list *list, list_node *node)
{
    if (list == NULL || node == NULL || list->head == NULL) return;

    list_node *ptr = list->head;
    list_node *tmp = NULL;

    if (ptr != NULL && ptr == node)  {

        list->head = ptr->next;
        return ;
    }

    while (ptr != NULL && ptr != node) {
            tmp = ptr;
            ptr = ptr->next;
        }
    
    if (NULL == ptr) return; //没有找到

    tmp->next = node->next;
    ptr->next = NULL;
    list->length --;

    if (NULL != list->free) {
        list->free(node->value);
        free(node);
        node = NULL;
    }

}

list_node *list_search_key(linked_list *list, void *key)
{
    if (list == NULL || key == NULL) return NULL;

    list_node *ptr = list->head;

    while (ptr != NULL) {
        if (NULL != list->match) {
            if (list->match(key, ptr->value) == 0) return ptr;
        } else { 
            if (*(int *)(ptr->value) == *(int *)key) {
                return ptr;
            }
        }
        ptr = ptr->next;
    }
    return NULL;
}

list_node *list_index(linked_list *list, int index)
{
    if (NULL == list) return NULL;
    if (index <= 0 || index >= list->length) return NULL;

    list_node *ptr = list->head;
    list_node *tmp = list->head;
    for(long i = 0; i <= index; i++) {
        tmp = ptr;
        ptr = ptr->next;
    }

    return tmp;
}

linked_list * list_rewind(linked_list *list)
{
    if (NULL == list) return NULL;

    list_node *old_head = list->head;
    list_node *new_head = NULL;
    list_node *tmp = NULL;

    while (NULL != old_head) {
        tmp = old_head->next;
        old_head->next = new_head;
        new_head = old_head;

        old_head = tmp; //指向下一个
    }
    list->head = new_head;
    return list;
}

size_t list_length(linked_list *list)
{
    if (NULL == list) return 0;
    return list->length;
}
